﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DSS_XNA.Engine.Error;
using DSS_XNA.Engine.Entities;
using Microsoft.Xna.Framework.Content;
using DSS_XNA.Engine.World;

namespace DSS_XNA.Engine.Objects
{
    public class ObjectManager
    {
        #region Properties

        public struct ObjectEventId
        {
            public string Name;
            public EventType EventType;
        }

        public Dictionary<ObjectEventId, string> ObjectEvents
        {
            get { return _objectEvents; }
            set { _objectEvents = value; }
        }
        private Dictionary<ObjectEventId, string> _objectEvents = new Dictionary<ObjectEventId, string>();

        #endregion

        #region Public Methods

        public ObjectManager()
        {
        }

        public Object CreateObject(string typeName, IWorld world, ContentManager content, string name, string assetName, float width, float height, float x, float y)
        {
            Object type = null;

            typeName = typeName.ToLower().Trim();
            //if (typeName == "bonusobject")
            //    type = new BonusObject();
            //else
                throw new DSSException(String.Format("Unknown object type: {0}", typeName));

            type.Load(world, content, name, assetName, width, height);
            type.Position.X = x;
            type.Position.Y = y;

            // does this object have any events to add?
            // OBJECT EVENTS ONLY GET ADDED WHEN THEY ARE CREATED
            foreach (KeyValuePair<ObjectEventId, string> pair in this.ObjectEvents)
            {
                if(pair.Key.Name == name)
                {
                    switch (pair.Key.EventType)
                    {
                        case EventType.Touch:
                            type.Touch += new DSS_XNA.Engine.Entities.Entity.OnTouchDelegate(type_Touch);
                            break;
                        default:
                            break;
                    }
                }
            }

            return type;
        }

        public void AddEvent(string eventType, string name, string command)
        {
            name = name.Trim().ToLower();

            ObjectEventId id = new ObjectEventId();
            id.EventType = this.GetEventType(eventType);
            id.Name = name;

            if (this.ObjectEvents.ContainsKey(id))
                return; // this object already has this event

            this.ObjectEvents.Add(id, command);
        }

        #endregion

        #region Private Methods

        private EventType GetEventType(string eventType)
        {
            eventType = eventType.ToLower().Trim();

            if (eventType == "touch")
                return EventType.Touch;

            throw new DSSException(String.Format("'{0}' is not a valid Object Event Type", eventType));
        }

        #endregion

        #region Events

        public void type_Touch(Entity sender, Entity entity)
        {
            if (sender == null)
                throw new DSSException("'sender' is null.");
            if (entity == null)
                throw new DSSException("'entity' is null.");

            ObjectEventId id = new ObjectEventId();
            id.EventType = EventType.Touch;
            id.Name = sender.Name;

            if (!this.ObjectEvents.ContainsKey(id))
                throw new DSSException(String.Format("There are no events assosiated with object named: {0}", id.Name));

            string action = this.ObjectEvents[id];
            Game1.ScriptManager.RunCommandRequest(action);
        }

        #endregion
    }
}
